#include "PhysicsUtils.h"
#include "ReusableBodyDef.h"

using namespace cmn;

ReusableBodyDef::ReusableBodyDef( float mass, float inertia, float friction, float resitution ) :
	m_friction( friction ),
	m_restitution( resitution )
{
	m_massData = new b2MassData();
	m_massData->mass = mass;
	m_massData->I = inertia;
	m_massData->center.SetZero();

	m_fixtureDefs = new Vector<b2FixtureDef*>();
}

ReusableBodyDef::~ReusableBodyDef()	 {
	delete m_massData;

	for( IteratorPtr<b2FixtureDef*> iter( m_fixtureDefs ); !iter.IsEnd(); iter.Next() ) {
		b2FixtureDef* fixtureDef = iter.Current();
		delete fixtureDef;
	}

	delete m_fixtureDefs;
}

void ReusableBodyDef::SetFriction( float friction ) {
	m_friction = friction;

	for( IteratorPtr<b2FixtureDef*> iter( m_fixtureDefs ); !iter.IsEnd(); iter.Next() ) {
		iter.Current()->friction = m_friction;
	}
}

void ReusableBodyDef::SetRestitution( float restitution ) {
	m_restitution = restitution;

	for( IteratorPtr<b2FixtureDef*> iter( m_fixtureDefs ); !iter.IsEnd(); iter.Next() ) {
		iter.Current()->friction = m_restitution;
	}
}

void ReusableBodyDef::AddCircle( const cmn::Circle& circle ) {
	b2Shape* shape = CreateCircle( circle );
	m_fixtureDefs->Add( CreateFixtureDef( shape ) );
}

void ReusableBodyDef::AddPolygon( const cmn::Polygon& polygon ) {
	b2Shape* shape = CreatePolygon( polygon );
	m_fixtureDefs->Add( CreateFixtureDef( shape ) );
}

b2FixtureDef* ReusableBodyDef::CreateFixtureDef( const b2Shape* shape ) {
	b2FixtureDef* fixtureDef = new b2FixtureDef();

	fixtureDef->shape = shape;
	fixtureDef->friction = m_friction;
	fixtureDef->restitution = m_restitution;

	return fixtureDef;
}

b2CircleShape* ReusableBodyDef::CreateCircle( const cmn::Circle& circle ) {
	b2CircleShape* shape = new b2CircleShape();
	shape->m_p = ToB2Vec2( circle.Center );
	shape->m_radius = circle.Radius;
	return shape;
}

b2PolygonShape* ReusableBodyDef::CreatePolygon( const cmn::Polygon& polygon ) {
	b2PolygonShape* shape = new b2PolygonShape();

	int count = polygon.GetVerticesCount();
	b2Vec2* b2Vertices = new b2Vec2[count];

	for( int i = 0; i < count; ++i ) {
		b2Vertices[i] = ToB2Vec2( polygon[i] );
	}

	shape->Set( b2Vertices, count );

	delete[] b2Vertices;
	return shape;
}
